#!/usr/bin/env python3
"""
压缩包管理工具 - 综合管理压缩和解压操作
功能：
1. 压缩包信息统计
2. 批量操作管理
3. 完整性检查
4. 清理和维护
"""

import os
import sys
import zipfile
from pathlib import Path
from typing import List, Dict
import argparse
import json
from datetime import datetime

class ArchiveManager:
    """压缩包管理器"""
    
    def __init__(self, archive_dir: str):
        self.archive_dir = Path(archive_dir)
        
    def analyze_all_archives(self) -> Dict:
        """分析所有压缩包"""
        if not self.archive_dir.exists():
            return {'error': f'目录不存在: {self.archive_dir}'}
        
        archives = list(self.archive_dir.glob("*.zip"))
        
        analysis = {
            'total_archives': len(archives),
            'total_files': 0,
            'total_size_mb': 0.0,
            'valid_archives': 0,
            'corrupted_archives': [],
            'archive_details': [],
            'year_distribution': {},
            'analysis_time': datetime.now().isoformat()
        }
        
        print(f"📊 分析 {len(archives)} 个压缩包...")
        
        for i, archive_path in enumerate(archives, 1):
            print(f"   {i}/{len(archives)}: {archive_path.name}")
            
            try:
                with zipfile.ZipFile(archive_path, 'r') as zipf:
                    file_list = zipf.namelist()
                    files = [f for f in file_list if not f.endswith('/')]
                    total_size = sum(info.file_size for info in zipf.infolist() if not info.is_dir())
                    
                    # 分析年份分布
                    years = set()
                    for file_path in files:
                        parts = file_path.split('/')
                        if len(parts) >= 2 and parts[1].isdigit():
                            years.add(parts[1])
                    
                    archive_info = {
                        'name': archive_path.name,
                        'file_count': len(files),
                        'size_mb': total_size / (1024 * 1024),
                        'years': sorted(list(years)),
                        'valid': True
                    }
                    
                    analysis['archive_details'].append(archive_info)
                    analysis['total_files'] += len(files)
                    analysis['total_size_mb'] += archive_info['size_mb']
                    analysis['valid_archives'] += 1
                    
                    # 统计年份分布
                    for year in years:
                        if year not in analysis['year_distribution']:
                            analysis['year_distribution'][year] = {
                                'archives': 0,
                                'files': 0,
                                'size_mb': 0.0
                            }
                        analysis['year_distribution'][year]['archives'] += 1
                        analysis['year_distribution'][year]['files'] += len([f for f in files if f'/{year}/' in f])
                        analysis['year_distribution'][year]['size_mb'] += archive_info['size_mb']
                
            except Exception as e:
                analysis['corrupted_archives'].append({
                    'name': archive_path.name,
                    'error': str(e)
                })
                analysis['archive_details'].append({
                    'name': archive_path.name,
                    'valid': False,
                    'error': str(e)
                })
        
        return analysis
    
    def print_analysis_report(self, analysis: Dict):
        """打印分析报告"""
        print("\n" + "="*80)
        print("📊 压缩包分析报告")
        print("="*80)
        
        # 基本统计
        print(f"📦 压缩包总数: {analysis['total_archives']}")
        print(f"✅ 有效压缩包: {analysis['valid_archives']}")
        print(f"❌ 损坏压缩包: {len(analysis['corrupted_archives'])}")
        print(f"📁 文件总数: {analysis['total_files']:,}")
        print(f"💾 总大小: {analysis['total_size_mb']:.1f} MB ({analysis['total_size_mb']/1024:.1f} GB)")
        
        # 损坏的压缩包
        if analysis['corrupted_archives']:
            print(f"\n❌ 损坏的压缩包:")
            for corrupt in analysis['corrupted_archives']:
                print(f"   - {corrupt['name']}: {corrupt['error']}")
        
        # 年份分布
        if analysis['year_distribution']:
            print(f"\n📅 年份分布:")
            print("-" * 60)
            print(f"{'年份':<8} {'压缩包数':<10} {'文件数':<12} {'大小(MB)':<12}")
            print("-" * 60)
            
            for year in sorted(analysis['year_distribution'].keys()):
                dist = analysis['year_distribution'][year]
                print(f"{year:<8} {dist['archives']:<10} {dist['files']:<12,} {dist['size_mb']:<12.1f}")
        
        # 压缩包详情
        print(f"\n📦 压缩包详情:")
        print("-" * 80)
        print(f"{'文件名':<30} {'文件数':<10} {'大小(MB)':<12} {'年份范围':<20} {'状态'}")
        print("-" * 80)
        
        for archive in analysis['archive_details']:
            name = archive['name'][:28] + ".." if len(archive['name']) > 30 else archive['name']
            
            if archive['valid']:
                file_count = f"{archive['file_count']:,}"
                size_mb = f"{archive['size_mb']:.1f}"
                years = f"{min(archive['years'])}-{max(archive['years'])}" if len(archive['years']) > 1 else archive['years'][0] if archive['years'] else "N/A"
                status = "✅ 正常"
            else:
                file_count = "N/A"
                size_mb = "N/A"
                years = "N/A"
                status = "❌ 损坏"
            
            print(f"{name:<30} {file_count:<10} {size_mb:<12} {years:<20} {status}")
    
    def save_analysis_report(self, analysis: Dict, output_file: str):
        """保存分析报告到文件"""
        output_path = Path(output_file)
        
        # 保存JSON格式
        json_file = output_path.with_suffix('.json')
        with open(json_file, 'w', encoding='utf-8') as f:
            json.dump(analysis, f, indent=2, ensure_ascii=False)
        
        # 保存文本报告
        txt_file = output_path.with_suffix('.txt')
        with open(txt_file, 'w', encoding='utf-8') as f:
            f.write("压缩包分析报告\n")
            f.write("="*50 + "\n\n")
            
            f.write(f"分析时间: {analysis['analysis_time']}\n")
            f.write(f"压缩包总数: {analysis['total_archives']}\n")
            f.write(f"有效压缩包: {analysis['valid_archives']}\n")
            f.write(f"损坏压缩包: {len(analysis['corrupted_archives'])}\n")
            f.write(f"文件总数: {analysis['total_files']:,}\n")
            f.write(f"总大小: {analysis['total_size_mb']:.1f} MB\n\n")
            
            if analysis['year_distribution']:
                f.write("年份分布:\n")
                f.write("-" * 40 + "\n")
                for year in sorted(analysis['year_distribution'].keys()):
                    dist = analysis['year_distribution'][year]
                    f.write(f"{year}: {dist['files']:,} 文件, {dist['size_mb']:.1f} MB\n")
        
        print(f"📄 报告已保存:")
        print(f"   JSON: {json_file}")
        print(f"   文本: {txt_file}")
    
    def check_integrity(self) -> Dict:
        """检查压缩包完整性"""
        archives = list(self.archive_dir.glob("*.zip"))
        
        results = {
            'total_checked': len(archives),
            'valid_archives': 0,
            'corrupted_archives': 0,
            'details': []
        }
        
        print(f"🔍 检查 {len(archives)} 个压缩包的完整性...")
        
        for i, archive_path in enumerate(archives, 1):
            print(f"   {i}/{len(archives)}: {archive_path.name}")
            
            try:
                with zipfile.ZipFile(archive_path, 'r') as zipf:
                    # 测试所有文件
                    bad_files = zipf.testzip()
                    
                    if bad_files is None:
                        results['valid_archives'] += 1
                        results['details'].append({
                            'name': archive_path.name,
                            'status': 'valid'
                        })
                        print(f"      ✅ 完整")
                    else:
                        results['corrupted_archives'] += 1
                        results['details'].append({
                            'name': archive_path.name,
                            'status': 'corrupted',
                            'bad_file': bad_files
                        })
                        print(f"      ❌ 损坏: {bad_files}")
                        
            except Exception as e:
                results['corrupted_archives'] += 1
                results['details'].append({
                    'name': archive_path.name,
                    'status': 'error',
                    'error': str(e)
                })
                print(f"      💥 错误: {e}")
        
        return results
    
    def cleanup_temp_files(self):
        """清理临时文件"""
        temp_patterns = ['*.tmp', '*.temp', '*~', '.DS_Store', 'Thumbs.db']
        
        cleaned_files = []
        for pattern in temp_patterns:
            for temp_file in self.archive_dir.glob(pattern):
                try:
                    temp_file.unlink()
                    cleaned_files.append(temp_file.name)
                except Exception as e:
                    print(f"❌ 无法删除 {temp_file.name}: {e}")
        
        if cleaned_files:
            print(f"🧹 清理了 {len(cleaned_files)} 个临时文件")
        else:
            print("✅ 没有发现临时文件")

def main():
    parser = argparse.ArgumentParser(description="压缩包管理工具")
    parser.add_argument("archive_dir", help="压缩包目录")
    parser.add_argument("-a", "--analyze", action="store_true", help="分析所有压缩包")
    parser.add_argument("-c", "--check", action="store_true", help="检查完整性")
    parser.add_argument("-r", "--report", help="保存分析报告到文件")
    parser.add_argument("--cleanup", action="store_true", help="清理临时文件")
    
    args = parser.parse_args()
    
    if not os.path.exists(args.archive_dir):
        print(f"❌ 目录不存在: {args.archive_dir}")
        sys.exit(1)
    
    manager = ArchiveManager(args.archive_dir)
    
    try:
        if args.analyze:
            analysis = manager.analyze_all_archives()
            manager.print_analysis_report(analysis)
            
            if args.report:
                manager.save_analysis_report(analysis, args.report)
        
        if args.check:
            results = manager.check_integrity()
            print(f"\n🔍 完整性检查结果:")
            print(f"   ✅ 有效: {results['valid_archives']}")
            print(f"   ❌ 损坏: {results['corrupted_archives']}")
        
        if args.cleanup:
            manager.cleanup_temp_files()
        
        if not any([args.analyze, args.check, args.cleanup]):
            print("❌ 请指定至少一个操作参数")
            parser.print_help()
    
    except Exception as e:
        print(f"💥 操作失败: {e}")
        sys.exit(1)

if __name__ == "__main__":
    main()
